package com.voice.call.service.impl;


import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import voice.voice.call.cache.NewsCountCache;

import com.voice.call.common.Const;
import com.voice.call.common.Result;
import com.voice.call.entity.News;
import com.voice.call.mapper.NewsMapper;
import com.voice.call.service.NewsService;
import com.voice.call.utils.DateUtil;
import com.voice.call.utils.HttpsUtil;
import com.voice.call.utils.JSONUtil;
import com.voice.call.utils.StringUtil;

@Service
public class NewsServiceImpl implements NewsService{
	
	private static final Logger log = LoggerFactory.getLogger(NewsServiceImpl.class);
	
	@Resource
	private Properties configProperties;
	
	@Resource
	private NewsCountCache newsCountCache;
	
	@Resource
	private NewsMapper newsMapper;
	
	@Override
	public void asyncEveryNewsList(){
		
		
		String dateStr = DateUtil.getNowDateTimeString(DateUtil.DATE_FMT);
		if (newsCountCache.hasExceedLimit(dateStr)) {
			//log.info("新闻同步超出了最大请求限制");
			return;
		}
		
		//分类
		String[] categoryList = {"business","entertainment","general","health","science","sports","technology"};
		
		String urlStr = configProperties.getProperty(Const.NEWS_URL);
		String appkey = configProperties.getProperty(Const.NEWS_APP_KEY);
		
		String usrTmp = String.format("%s?country=%s&apiKey=%s", urlStr,"us",appkey)+"&category=%s";
		//获取url
		List<String> urlList = new ArrayList<String>();
		for (int i = 0; i < categoryList.length; i++) {
			urlList.add(String.format(usrTmp, categoryList[i]));
		}
		
		new Thread(new NewsThread(categoryList,urlList, this,newsCountCache)).start();
	}
	
	//清空历史数据
	@Override
	public  void clearHistoryNews(){
		Date noDate = new Date();
		Date prvDate = DateUtil.addDate(noDate, -6); //清空6天前数据
		
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("published", prvDate);
		newsMapper.deleteHistoryData(params);
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public void asyncNewsRequest(String url,String category) {
		
		try {
			
			//log.info("同步新闻url={}",url);
			String jsonStr =HttpsUtil.doGetCloseableHttpSSL(url, null);
			Map<String,Object> rsMap= JSONUtil.jsonToMap(jsonStr);
			if(rsMap!=null && rsMap.get("status")!=null &&rsMap.get("status").equals("ok")){
				
				//articles
				List<Map<String,Object>> list=(List<Map<String,Object>>)rsMap.get("articles");
				
			    if(list!=null && !list.isEmpty()){
			    	
			    	List<News> addList = new ArrayList<News>();
			    	for (Map<String,Object> itemMap:list) {
			    		News entityNews = this.mapToNews(itemMap, category);
			    		if(entityNews!=null && !StringUtil.isEmpty(entityNews.getDesc()) && !StringUtil.isEmpty(entityNews.getImage())){
			    			log.info("getImage = {}",entityNews.getImage());
			    			addList.add(entityNews);
			    		}
					}
			    	if (!addList.isEmpty()) {
			    		
			    		for (News news : addList) {
			    			try {
			    				newsMapper.insert(news);
							} catch (Exception e) {
								e.printStackTrace();
							}
			    			
						}
			    		/***
						int total = newsMapper.insertNewsBatch(addList);
						if (total >0) {
							//log.info("批量新增新闻成功,category={}",category);
						}else{
							//log.info("批量新增新闻失败,category={}",category);
						}
						**/
					}else {
						//log.info("没有批量新增新闻数据,category={}",category);
					}
			    }
			}
			
			//删除为空数据
			newsMapper.deleteNullData();
			
		} catch (Exception e) {
			e.printStackTrace();
			//log.error("新闻同步url={},发生异常",url);
		}
		
		
	}
	
	@SuppressWarnings("unchecked")
	private News mapToNews(Map<String,Object> itemMap,String category){
		
		try {
			
			News entity = new News();
			entity.setCategory(category);
			if(itemMap.get("source")!=null){
				Map<String,Object> sorceMap = (Map<String,Object>)itemMap.get("source");
				if(sorceMap!=null&&sorceMap.get("name")!=null&&!StringUtil.isEmpty((String)sorceMap.get("name"))){
					entity.setName(sorceMap.get("name").toString());
				}
			}
			if(itemMap.get("author")!=null){
				entity.setAuthor(itemMap.get("author").toString());
			}
			if(itemMap.get("title")!=null){
				entity.setTitle(itemMap.get("title").toString());
			}
			if(itemMap.get("description")!=null){
				entity.setDesc(itemMap.get("description").toString());
			}
			if(itemMap.get("url")!=null){
				entity.setUrl(itemMap.get("url").toString());
			}
			if(itemMap.get("urlToImage")!=null){
				entity.setImage(itemMap.get("urlToImage").toString());
			}
			
			String timeStr =null;
			if(itemMap.get("publishedAt")!=null){
				timeStr = itemMap.get("publishedAt").toString().replaceAll("[a-zA-Z]+", " ");
				entity.setPublished(DateUtil.parse(timeStr, DateUtil.DATE_TIME_FMT));
				//entity.setImage(itemMap.get("publishedAt").toString());
			}
			entity.setLang(Const.LANGUAGE);
			entity.setCountry("us");
			entity.setCtime(new Date());
			entity.setMtime(new Date());
			
			if(StringUtil.isEmpty(timeStr)){
				//log.info("未取到新闻发布时间!category={}",category);
				return null;
			}
			//判断新闻是否存在
			Map<String,Object> paramsMap =new HashMap<String, Object>();
			paramsMap.put("title", entity.getTitle());
			paramsMap.put("published", timeStr);
			paramsMap.put("category", category);
			int total = newsMapper.existsCount(paramsMap);
			if (total >0) {
				//log.info("同步的新闻已存在!");
				return null;
			}
			return entity;
			
		} catch (Exception e) {
			e.printStackTrace();
			//log.error("解析新闻失败");
			return null;
		}
		
	}
	
	@Override
	public Result getNewsPageList(String lang,String country,String category,Integer page,Integer pageSize){
		Map<String, Object> parMap = new HashMap<String, Object>();
		if(!StringUtil.isEmpty(lang)){
			parMap.put("lang", lang);
		}
		if(!StringUtil.isEmpty(country)){
			parMap.put("country", country);
		}
		if(!StringUtil.isEmpty(category)){
			parMap.put("category", category);
		}
		parMap.put("curpage", (page-1)*pageSize);
		parMap.put("pagesize", pageSize);
		
		int total = newsMapper.count(parMap);
		int maxpage = total%pageSize == 0?total/pageSize : (total/pageSize)+1;
		
		Map<String,Object> newsMap = new HashMap<String, Object>();
		newsMap.put("page", page);
		newsMap.put("pagesize", pageSize);
		newsMap.put("total", total);
		newsMap.put("maxpage", maxpage);
        if (page>maxpage) {
        	newsMap.put("list", new ArrayList<News>());
        	return new Result(newsMap);
		}
		List<News> list = newsMapper.list(parMap);
		newsMap.put("list", list);
		return new Result(newsMap);
	}
	
	/****
	@Override
	public Result getNewsPageList(String lang,String country,String category,String page,String pageSize){
		
		try {
			
			String urlStr = configProperties.getProperty(Const.NEWS_URL);
			String appkey = configProperties.getProperty(Const.NEWS_APP_KEY);
			String nowTimeStr = DateUtil.getNowDateTimeString(DateUtil.DATE_FMT);
			StringBuilder params = new StringBuilder();
			params.append(String.format("%s?apiKey=%s", urlStr,appkey));
			if(!StringUtil.isEmpty(lang)){
				params.append(String.format("&language=%s", lang));
			}
			if(!StringUtil.isEmpty(country)){
			    params.append(String.format("&country=%s", country));
			}
			if(!StringUtil.isEmpty(category)){
			    params.append(String.format("&category=%s", category));
			}
			params.append(String.format("&page=%s", page));
			params.append(String.format("&pageSize=%s", pageSize));
			params.append(String.format("&from=%sT00:00:00", nowTimeStr));
			params.append(String.format("&to=%sT23:59:59", nowTimeStr));
			log.info("新闻请求url={}",params.toString());
			String jsonStr =HttpsUtil.doGetCloseableHttpSSL(params.toString(), null);
			
			log.info("新闻请求结果={}",jsonStr);
			Map<String,Object> rsMap= JSONUtil.jsonToMap(jsonStr);
			if(rsMap!=null){
				
				Map<String,Object> newsMap = new HashMap<String, Object>();
				newsMap.put("page", page);
				newsMap.put("pagesize", pageSize);
				if (rsMap.get("status")!=null && rsMap.get("status").toString().equals("ok")) {
					log.info("新闻请求成功");
					newsMap.put("total", rsMap.get("totalResults"));
					newsMap.put("list", rsMap.get("articles"));
					
				}else {
					log.info("新闻请求失败");
					newsMap.put("total", 0);
					newsMap.put("list", new ArrayList<Map<String, Object>>());
				}
				return new Result(newsMap);
				
			}else{
				log.info("新闻请求数据解析失败");
				return new Result(ResultEnum.JSON_PARSE_ERROR);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			log.error("新闻请求发生异常");
			return new Result(ResultEnum.HTTP_CONNECT_ERROR);
		}
		
	}
	***/
	
	//线程处理同步更新
	class NewsThread implements Runnable{
		List<String> urlList;
		NewsService newsService;
		String[] categoryList;
		NewsCountCache newsCountCache;
		
		NewsThread(String[] categoryList,List<String> urlList,NewsService newsService,NewsCountCache newsCountCache){
			this.categoryList = categoryList;
			this.urlList = urlList;
			this.newsService = newsService;
			this.newsCountCache = newsCountCache;
		}
		
		@Override
		public void run() {
			
			for (int i = 0; i < this.urlList.size(); i++) {
				this.newsService.asyncNewsRequest(this.urlList.get(i), this.categoryList[i]);
			}
			String dateStr = DateUtil.getNowDateTimeString(DateUtil.DATE_FMT);
			this.newsCountCache.increase(dateStr, this.urlList.size());
		}
	}

}
